﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SkypeStudio.Controls.Views;
using System.Threading;
using System.Windows.Threading;
using System.Collections.ObjectModel;
using SkypeStudio.Controls.Model;
using SkypeStudio.Controls.Services;
using SkypeStudio.Framework;
using System.Windows.Data;
using System.ComponentModel;
using System.Windows.Input;

namespace SkypeStudio.Controls.ViewModels
{
    public class ContactListViewModel : ViewModelBase<IContactListView>, IDisposable
    {
        private  ISkypeApplicationService _SkypeService;

        #region Constructor
        public ContactListViewModel(IContactListView view, ISkypeApplicationService skypeService)
            : base(view)
        {
            if (skypeService == null)
                throw new ArgumentNullException("skypeService");

            _SkypeService = skypeService;
            _SkypeService.SkypeProcessAttachStatusChanged += SkypeServiceSkypeProcessAttachStatusChanged;
            _SkypeService.ContactOnlineStatusChanged += SkypeServiceContactOnlineStatusChanged;
            
        }

        void SkypeServiceContactOnlineStatusChanged(Contact c)
        {
            var contact = ContactList.First(o => o.Handle == c.Handle);
            contact.OnlineStatus = c.OnlineStatus;

            ICollectionView collectionView = CollectionViewSource.GetDefaultView(ContactList);
            collectionView.Refresh();
        }

        void SkypeServiceSkypeProcessAttachStatusChanged(SkypeProcessAttachStatus obj)
        {
            NotifyOfPropertyChange(() => ContactList);
            NotifyOfPropertyChange(() => IsSkypeProcessAttachedReady);
            NotifyOfPropertyChange(() => IsNoySkypeProcessAttachedReady);
        }

        #endregion

        ObservableCollection<Contact> _ContactList;
        public ObservableCollection<Contact> ContactList
        {
            get
            {
                if (_ContactList == null)
                {
                    _ContactList =  new ObservableCollection<Contact>(_SkypeService.GetContactList());
                }

                return _ContactList;
            }
        }

        private object _SelectedContact;
        public object SelectedContact
        {
            get
            {
                return _SelectedContact;
            }
            set
            {
                if (_SelectedContact == value)
                    return;
                _SelectedContact = value;
                NotifyOfPropertyChange(() => SelectedContact);
            }
        }

        public bool IsSkypeProcessAttachedReady
        {
            get { return _SkypeService.SkypeProcessAttachStatus == SkypeProcessAttachStatus.apiAttachSuccess; }
        }

        public bool IsNoySkypeProcessAttachedReady
        {
            get { return !IsSkypeProcessAttachedReady; }
        }

        public void Dispose()
        {
            if (_SkypeService != null)
            {
                _SkypeService.SkypeProcessAttachStatusChanged -= SkypeServiceSkypeProcessAttachStatusChanged;
                _SkypeService.SkypeProcessAttachStatusChanged -= SkypeServiceSkypeProcessAttachStatusChanged;
                _SkypeService = null;
            }

        }

        private ICommand _ListMouseDoubleClickCommand;
        public ICommand ListMouseDoubleClickCommand
        {
            get
            {
                if (_ListMouseDoubleClickCommand == null)
                {
                    _ListMouseDoubleClickCommand = new RelayCommand(ListMouseDoubleClick);
                }
                return _ListMouseDoubleClickCommand;
            }

        }

        void ListMouseDoubleClick(object param)
        {
            var c = SelectedContact as Contact;

            Chat chat = _SkypeService.CreateChat(c);
            OnRequestOpendChat(chat);
        }

        private void OnRequestOpendChat(Chat chat)
        {
            Action<Chat> handler = RequestStartChat;
            if (handler != null)
                handler(chat);
        }
        public event Action<Chat> RequestStartChat;
    }
}
